package common

import (
	"encoding/csv"
	"fmt"
	"gitee.com/wangyexin/my-tools/domains/outs"
	"os"
	"reflect"
	"time"
)

func GetCsv(fPath string) outs.Response {
	file, err := os.Open(fPath)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()
	reader := csv.NewReader(file)
	reader.FieldsPerRecord = -1
	record, err2 := reader.ReadAll()
	if err2 != nil {
		fmt.Println(err2)
	}
	var res []map[string]any
	var key []string
	for idx, item := range record {
		if idx == 0 {
			key = item
			// fmt.Println(key)
			continue
		}
		rowDict := make(map[string]any)
		//res = append(res, item)
		for i, v := range item {
			k := key[i]
			rowDict[k] = v
		}
		//fmt.Println(rowDict)
		res = append(res, rowDict)
	}
	return outs.OkWithData(res)

}

type Csv[T any] struct {
	f *os.File
	w *csv.Writer
}

// ExportExcelByStruct 导出excel 数据源为[]Struct
func NewCsv[T any](f *os.File) (*Csv[T], error) {
	o := new(T)
	c := Csv[T]{}
	c.f = f
	w := csv.NewWriter(f)
	c.w = w
	headers := make([]string, 0)
	t := reflect.TypeOf(o).Elem()
	fieldNum := t.NumField()
	for i := 0; i < fieldNum; i++ {
		name := t.Field(i).Tag.Get("name")
		if name != "" {
			headers = append(headers, name)
		} else {
			headers = append(headers, t.Field(i).Name)
		}
	}

	w.Write(headers)
	w.Flush()
	return &c, nil
}

// ExportExcelByStruct 导出excel 数据源为[]Struct
func (c Csv[T]) WriteCsv(datas []T) error {
	t := reflect.TypeOf(datas[0])
	if t.Kind() != reflect.Struct {
		return fmt.Errorf("data 数据格式不正确")
	}
	for _, data := range datas {
		row := make([]string, 0)
		fieldNum := t.NumField()
		for i := 0; i < fieldNum; i++ {
			t := reflect.TypeOf(data)
			v := reflect.ValueOf(data)
			field := v.Field(i).Interface()
			switch value := field.(type) {
			case time.Time:
				val := value.Format("2006-01-02 15:04:05")
				dateFormat := t.Field(i).Tag.Get("dateFormat")
				if dateFormat != "" {
					val = value.Format(dateFormat)
				}
				if val == "0001-01-01 00:00:00" {
					val = ""
				}
				row = append(row, val)
			default:
				row = append(row, fmt.Sprint(value))
			}
		}
		c.w.Write(row)
	}
	c.w.Flush()
	return nil
}
